#include "Knight.hpp"
#include "CriticalException.hpp"
#include "Cell.hpp"



Knight::Knight(Chess::Color color, const Position& pos)
	: Piece(color, Piece::KNIGHT, pos)
{}

Knight::~Knight()
{}

list<Position*>	Knight::getPossibleCases() const
{
	if (this->isOut())
		throw new CriticalException("Knight :: getPossibleCases : Trying to get possible cases while piece is out !");
		
	Position current = this->getCell()->getPosition();
	list<Position*> valables;
	
	
	current.setColor(this->color);
	
	int x, y, xtmp, ytmp;
	
	x = current.getX();
	y = current.getY();
	
	// UP
	ytmp = y + 2;
	xtmp = x - 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(
			(
				(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
				(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
			)
			|| 
			(!(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		))
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	xtmp = x + 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
	
	// LEFT
	xtmp = x - 2;
	ytmp = y - 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	ytmp = y + 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	// RIGHT
	xtmp = x + 2;
	ytmp = y - 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	ytmp = y + 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	// DOWN
	ytmp = y - 2;
	xtmp = x - 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));
		
	xtmp = x + 1;
	
	if (Position::isGood(xtmp, ytmp) && 
		(((Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()) && 
		(Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->getPiece()->getColor() != this->color)
		) || (!Chess::getInstance()->getChessboard()->getCell(Position(xtmp, ytmp, this->color))->hasPiece()))
		)
		valables.push_back(new Position(xtmp, ytmp, this->color));

	return valables;
}
		
